package de.gof.ppstool.bestellverwaltung.db;

import static de.gof.ppstool.bestellverwaltung.db.Bestellung.FINDE_ALLE_BESTELLUNGEN;
import static de.gof.ppstool.bestellverwaltung.db.BestellpositionEntity.FINDE_ALLE_BESTELLPOSITIONEN;
import static MANDATORY;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional(propagation = MANDATORY)
public class BestellverwaltungDAO implements IBestellverwaltungDAO,
		Serializable {
	/** 
	 */

	private static final long serialVersionUID = 4988814553174729034L;
	@PersistenceContext
	private EntityManager em;

	public BestellverwaltungDAO() {
		super();
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public BestellpositionEntity erstelleBestellposition(
			BestellpositionEntity bestellposition) {
		em.persist(bestellposition);
		return bestellposition;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public Bestellung erstelleBestellung(Bestellung bestellung) {
		em.persist(bestellung);
		return bestellung;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public BestellpositionEntity aendereBestellpostion(
			BestellpositionEntity bestellposition) {
		bestellposition = em.merge(bestellposition);
		return bestellposition;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public Bestellung aendereBestellung(Bestellung bestellung) {
		bestellung = em.merge(bestellung);
		return bestellung;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void loescheBestellposition(BestellpositionEntity bestellpostion) {
		if (bestellpostion == null) {
			return;
		}

		if (!em.contains(bestellpostion))
			bestellpostion = em.find(BestellpositionEntity.class,
					bestellpostion.getBestellpositionId());

		em.remove(bestellpostion);
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void loescheBestellung(Bestellung bestellung) {
		if (bestellung == null) {
			return;
		}

		if (!em.contains(bestellung))
			bestellung = em
					.find(Bestellung.class, bestellung.getBestellungId());

		em.remove(bestellung);
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	@SuppressWarnings("unchecked")
	public List<BestellpositionEntity> findeAlleBestellpositionen()
			throws BestellpositionNotFoundException {
		final Query query = em.createNamedQuery(FINDE_ALLE_BESTELLPOSITIONEN);
		final List<BestellpositionEntity> result = query.getResultList();
		return result;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	@SuppressWarnings("unchecked")
	public List<Bestellung> findeAlleBestellungen()
			throws BestellungNotFoundException {
		final Query query = em.createNamedQuery(FINDE_ALLE_BESTELLUNGEN);
		final List<Bestellung> result = query.getResultList();
		return result;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public BestellpositionEntity findeBestellpositionNachId(
			Long bestellpositionId) throws BestellpositionNotFoundException {
		Query query = em
				.createNamedQuery(BestellpositionEntity.FINDE_BESTELLPOSITION_NACH_ID);
		query.setParameter(BestellpositionEntity.PARAM_BESTELLPOSITION_ID,
				bestellpositionId);
		BestellpositionEntity bestellposition = null;
		try {
			bestellposition = (BestellpositionEntity) query.getSingleResult();
		} catch (Exception e) {

			//e.printStackTrace();
		}

		if (bestellposition == null) {
			final BestellpositionNotFoundException e = new BestellpositionNotFoundException(
					bestellpositionId);
			throw e;
		}

		return bestellposition;
	}

	/**
	 * { @inheritDoc}
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public Bestellung findeBestellungNachId(Long bestellungId)
			throws BestellungNotFoundException {
		Query query = em.createNamedQuery(Bestellung.FINDE_BESTELLUNG_NACH_ID);
		query.setParameter(Bestellung.PARAM_BESTELLUNG_ID, bestellungId);
		Bestellung bestellung = null;
		try {
			bestellung = (Bestellung) query.getSingleResult();
		} catch (Exception e) {

			//e.printStackTrace();
		}

		if (bestellung == null) {
			final BestellungNotFoundException e = new BestellungNotFoundException(
					bestellungId);
			throw e;
		}

		return bestellung;
	}

}
